#
# "@(#) $Id: MP3Track.py,v 1.1.1.1 2006-07-27 03:16:08 gioshe Exp $"
#
# This work is released under the GNU GPL, version 2 or later.
#
from Track import *
from time import *
import os
import pyid3lib
import Utils.mp3Info
#import traceback
import Utils.Settings
from Utils.Settings import *

stream = None # persistent stream to work around bug in  xine_dispose()

# work around bug in pyid3lib which leaves a trailing null on the string
# also kill any leading or trailing whitespace
def trimNulls(s):
	while s[-1:]=='\0':
		s = s[0:-1]
	return s.strip()
	
class MP3Track(XineTrack):
	def __init__(self,library = None):
		XineTrack.__init__(self,library)
	
	#
	# load any ID3 tags that are contained in the MP3 file
	#
	def setFile(self,filePath,thread = None):
		global stream
		if type(filePath).__name__=='unicode':
			filePath = filePath.encode('latin-1')
		stats = os.stat(filePath)
		self.size = stats[6]
		self.location = filePath
		tags = pyid3lib.tag(filePath)
		for i in tags: blah = i # XXX DSM weird workaround for UTF-16 tags
		(srcPath,fileName) = os.path.split(filePath)
		(rootName,extension) = os.path.splitext(fileName)
		title = rootName
		try: title = trimNulls(tags.title)
		except: pass
		artist = ""
		try: artist = trimNulls(tags.artist)
		except: pass
		album = ""
		try: album = trimNulls(tags.album)
		except: pass
		self.title = title
		self.artist = artist
		self.album = album
		try: self.contentType = trimNulls(tags.contenttype)
		except: pass
		try: self.composer = trimNulls(tags.composer)
		except: pass
		try: self.year = int(tags.year)
		except: pass
		try: self.encodedBy = trimNulls(tags.encodedby)
		except: pass
		try: self.dateEncoded = strptime(tags.date,"%Y-%m-%dT%H:%M:%S")
		except: pass
		try:
			trackTuple = tags.tracknum
			self.trackNum = trackTuple[0]
			self.trackCount = trackTuple[1]
		except: pass
		try:
			discTuple = tags.partinset
			self.discNum = discTuple[0]
			self.discCount = discTuple[1]
		except: pass
		self.kind = "MPEG audio file"
		fd = open(self.location)
		try:
			info = mp3Info.MP3Info(fd)
			self.bitRate = info.bitrate
			self.sampleRate = info.samplerate
			if info.vbr: xbr = "VBR"
			else: xbr = "CBR"
			self.format = "MPEG-%d, Layer %d %s" % (info.version,info.layer,xbr)
			mode = info.mode
			self.mode = mode.title()
			if mode=='mono': self.channels = 1
			else: self.channels = 2
			self.totalTime = info.totalTime
			if info.id3v2:
				self.id3Version = 'v2.%d.%d' % (info.id3v2_major_version,info.id3v2_minor_version)
			elif info.id3v1:
				self.id3Version = 'v1.%d' % info.id3v1_major_version
		except: pass
		fd.close()
	file = property(None,setFile)

	#
	# fetch the (first) artwork for this track
	#
	def getImage(self):
		location = self.location
		#print "attempting to get art from",self.location
		#try:
		try:
			tag = pyid3lib.tag(location)
			#traceback.print_stack()
			return tag[tag.index('APIC')]['data']
		except:
			return XineTrack.getImage(self)
			
##	def setImage(self,imageURL):
##		print "attempting to set image", imageURL
##		tag = pyid3lib.tag(self.location)
##		try:
##			tag.remove('APIC')
##			print "removing pic"
##		except:
##			pass
##		if imageURL == None:
##			tag.update()
##			print "tag removed"
##			return
##			#d = { 'frameid' : 'APIC', 'mimetype' : 'image/jpeg','description' : 'null picture','picturetype' : 3,'data' : 0 }
##		else:
##			#try:
##			f = open( imageURL, 'rb' )
##			d = { 'frameid' : 'APIC', 'mimetype' : 'image/jpeg','description' : 'Front cover','picturetype' : 3,'data' : f.read() }
##			f.close()
##			tag.append( d )
##		print "SET PIC DID WORK"
##		tag.update()
##			#except:
##			#	print "SET PIC DIDN'T WORK"
##			#	return None
##	image = property(getImage,setImage)
	
	def setImage(self, image):
		#print "attempting to set image"
		tag = pyid3lib.tag(self.location)
		try:
			tag.remove('APIC')
			#print "removing pic"
		except:
			pass
		if image == None:
				tag.update()
				#print "tag removed"
				return
		else:
			d = { 'frameid' : 'APIC', 'mimetype' : 'image/jpeg','description' : 'Front cover','picturetype' : 3,'data' : image }
			tag.append( d )
		#print "SET PIC DID WORK"
		tag.update()
	image = property(getImage,setImage)		
	#
	# handle any tags that MP3s can store in ID3 tags
	#
	def loadTagsFrom(self,tags):
		#print "loading tags from",tags
		if tags==None or len(tags)==0: return
		XineTrack.loadTagsFrom(self,tags)
		if self.managed or Settings.settings().get('Modify Tags',False):
			#print "setting tags"
			id3 = pyid3lib.tag(self.location)
			try: id3.artist = unikode(tags['artist']).encode('latin-1')
			except: pass
			try: id3.album = unikode(tags['album']).encode('latin-1')
			except: pass
			try: id3.title = unikode(tags['title']).encode('latin-1')
			except: pass
			try: id3.year = int(tags['year'])
			except: pass
			try: id3.composer = unikode(tags['composer']).encode('latin-1')
			except: pass
			try: id3.track = (self.trackNum,self.trackCount)
			except: pass
			try: id3.partinset = (self.discNum,self.discCount)
			except: pass
			try: id3.contenttype = self.contentType
			except: pass
			try: id3.bpm = int(tags['bpm'])
			except: pass
			# XXX DSM add other stuff here!
			id3.update()
			#print "tags set"
